// webpack 是 node 写出来的 node 的写法

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

// 配套使用 start  ==》 使用了css 压缩 webpack 默认的 js 压缩就会失效，所以要配套使用
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
// 配套使用 end

const webpack = require('webpack');

module.exports = {
  devServer: { // 开发服务器的配置
    port: 3000,
    progress: true,
    contentBase: './build',
    open: true, // 自动打开浏览器
    compress: true, // gzip 压缩
  },
  mode: 'development',// 模式 默认两种 production development
  entry: './src/index.js',//  入口
  output: {
    filename: 'bundle.[hash:8].js', // 打包后文件名 加 hash 防止缓存
    path: path.resolve(__dirname, 'build'), // 路径必须是一个绝对路径
  },
  optimization: { // 优化项
    minimizer: [
      new UglifyJsPlugin({
        cache: true,
        parallel: true, // 并发打包，一起压缩多个
        sourceMap: true // 源码映射，调试时使用 set to true if you want JS source maps
      }),
      new OptimizeCssAssetsPlugin({})
    ]
  },
  plugins: [ // 数组 防止所有 webpack 插件
    new HtmlWebpackPlugin({
      template: "./src/index.html", // 模版文件位置
      filename: "index.html", // 打包后的名字
      minify: { // 压缩 index.html
        removeAttributeQuotes: true, // 删除属性的双引号
        // collapseWhitespace: true, // 删除空格 压缩为一行
      },
      hash: true, // 加上 hash 串 防止系统缓存引起的 页面不更新
    }),
    new MiniCssExtractPlugin({ // 抽离 css 到一个文件中
      filename: 'main.css',
    }),
    // new webpack.ProvidePlugin({ // 在每个模块中 都注入 $
    //   $: 'jquery',
    // }),
  ],
  externals:{
    jquery:'$' // 外部引用的 jquery 并不需要打包
  },
  module: { // 模块
    rules: [ // 规则
      // {  // jquery 暴露给全局
      //   test:require.resolve('jquery'),
      //   use:'expose-loader?$',
      // },

      // { // loader 默认从右向左执行，从下到上执行
      //   enforce: "pre", // previous post 强制在 转换 js 的 loader 的 最前面执行检查代码
      //   test: /\.js$/,
      //   exclude: /node_modules/,
      //   loader: "eslint-loader",
      // },
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: { // 用 babel-loader 需要把 es6 转换成 es5
            presets: [
              '@babel/preset-env'
            ],
            plugins: [
              ["@babel/plugin-proposal-decorators", {"legacy": true}],
              ["@babel/plugin-proposal-class-properties", {"loose": true}],
              '@babel/plugin-transform-runtime'
            ]
          },
        },
        include: path.resolve(__dirname, 'src'),
        exclude: /node_modules/
      },
      // css-loader 解析 @import 这种语法 解析路径
      // style-loader 把 css 插入到 head 标签中
      // loader 特点 功能单一
      // loader 的用法 字符串  只用一个 loader
      // 多个 loader 需要 []
      // loader 顺序 默认是从右向左，从下至上执行
      // loader 还可以写成对象模式  {loader: 'css-loader', options: {...}}
      {
        test: /\.css$/, use: [
          // {
          //   loader: 'style-loader',
          //   options: {
          //     insertAt: 'top', // 让模版中的 style 优先级更高，将生成的 style 放在上面
          //   }
          // },
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
        ]
      },
      {
        // 可以处理 less sass stylus node-sass sass-loader
        // stylus stylus-loader
        test: /\.less$/, use: [
          // {
          //   loader: 'style-loader',
          //   options: {
          //     insertAt: 'top', // 让模版中的 style 优先级更高，将生成的 style 放在上面
          //   }
          // },
          MiniCssExtractPlugin.loader,
          'css-loader', // @import 解析路径
          'postcss-loader',
          'less-loader', // 把 less -》 css
        ]
      }
    ]
  }
};
